home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / Sample 2.4 Think C distribution / prog.c < prev    next >
Text File  |  1991-02-25  |  16KB  |  631 lines

  1. /*______________________________________________________________________
  2.  
  3.     Sample - Disinfectant Sample Code.
  4.     
  5.     Version 2.4.
  6.  
  7.     John Norstad
  8.     Academic Computing and Network Services
  9.     Northwestern University
  10.     2129 Sheridan Road
  11.     Evanston, IL 60208
  12.  
  13.     Bitnet: jln@nuacc
  14.     Internet: jln@acns.nwu.edu
  15.     AppleLink: a0173
  16.     CompuServe: 76666,573
  17.     
  18.     Copyright © 1988, 1989, 1990 Northwestern University.  Permission is granted
  19.     to use this code in your own projects, provided you give credit to both
  20.     John Norstad and Northwestern University in your about box or document.
  21. _____________________________________________________________________*/
  22.  
  23.  
  24. /*______________________________________________________________________
  25.     
  26.     prog.c - Sample Main Module.
  27.  
  28.     This is the main module for Sample.  It contains the basic
  29.     main event loop processing.
  30. _____________________________________________________________________*/
  31.  
  32.  
  33. #include "utl.h"
  34. #include "rez.h"
  35. #include "glob.h"
  36. #include "wstm.h"
  37. #include "abou.h"
  38. #include "pref.h"
  39. #include "help.h"
  40. #include "main.h"
  41. #include "misc.h"
  42. #include "scan.h"
  43. #include "init.h"
  44. #include "prog.h"
  45.  
  46. #define nil 0
  47.  
  48. #define         osEvt                     app4Evt    /* Cribbing from CSwitchBoard.c */
  49. #define        suspendResumeMessage    0x01        /* Suspend/Resume event code        */
  50. #define        ResumeEvtMask            0x1        /* Supend or Resume selector        */
  51.  
  52. extern void _DataInit();
  53.  
  54. /*_____________________________________________________________________
  55.  
  56.     Global Variables.
  57. _____________________________________________________________________*/
  58.  
  59.  
  60. static WindowPtr            Front;                /* ptr to front window */
  61. static WindowObject        *FrontObj;            /* ptr to front window object */
  62. static WindKind            FrontKind;            /* front window kind */
  63.  
  64. /*_____________________________________________________________________
  65.  
  66.     Command - Process a Command.
  67.     
  68.     Entry:        mResult = 16/menu number, 16/item number.
  69. _____________________________________________________________________*/
  70.  
  71.  
  72. static void Command (long mResult)
  73.  
  74. {
  75.     short                 theMenu;                /* menu number */
  76.     short                    theItem;                /* item number */
  77.     Str255                daName;                /* desk accessory name */
  78.     GrafPtr                 savePort;            /* saved grafport */
  79.  
  80.     /* Extact the item and menu numbers. */
  81.  
  82.     theItem = mResult & 0xffff;
  83.     theMenu = (mResult >> 16) & 0xffff;
  84.     
  85.     /* Check for and process help mode. */
  86.     
  87.     if (HelpMode && (theMenu != appleMID || theItem <= helpCommand)) {
  88.         if (theMenu) 
  89.             help_Open(tagCmdBase + tagCmdMult*(theMenu-appleMID) + theItem);
  90.         HiliteMenu(0);
  91.         return;
  92.     };
  93.  
  94.     switch (theMenu) {
  95.     
  96.         /* Process the command. */
  97.     
  98.         case appleMID:
  99.         
  100.             if (theItem == aboutCommand) {
  101.                 abou_Open();
  102.             } else if (theItem == helpCommand) {
  103.                 help_Open(0);
  104.             } else {
  105.                 GetItem(GetMHandle(appleMID), theItem, daName);
  106.                 GetPort(&savePort);
  107.                 (void) OpenDeskAcc(daName);
  108.                 SetPort(savePort);
  109.             };
  110.             break;
  111.  
  112.         case fileMID:
  113.         
  114.             switch (theItem) {
  115.                 case closeCommand:
  116.                     if (FrontKind == daWind) {
  117.                         CloseDeskAcc(((WindowPeek)Front)->windowKind);
  118.                     } else {
  119.                         if (FrontObj->close) (*FrontObj->close)();
  120.                     };
  121.                     break;
  122.                 case saveAsCommand:
  123.                     if (FrontObj->save) (*FrontObj->save)();
  124.                     break;
  125.                 case pageSetupCommand:
  126.                     if (FrontObj->pageSetup) {
  127.                         PrOpen();
  128.                         misc_PrintError((*FrontObj->pageSetup)());
  129.                         PrClose();
  130.                     };
  131.                     break;
  132.                 case printCommand:
  133.                     if (FrontObj->print) {
  134.                         PrOpen();
  135.                         misc_PrintError((*FrontObj->print)((Boolean)false));
  136.                         PrClose();
  137.                     };
  138.                     break;
  139.                 case printOneCommand:
  140.                     if (FrontObj->print) {
  141.                         PrOpen();
  142.                         misc_PrintError((*FrontObj->print)((Boolean)true));
  143.                         PrClose();
  144.                     };
  145.                     break;
  146.                 case prefsCommand:
  147.                     pref_Open();
  148.                     break;
  149.                 case quitCommand:
  150.                     Done = true;
  151.                     if (Scanning) {
  152.                         Scanning = FloppyWait = false;
  153.                         Canceled = true;
  154.                         InitCursor();
  155.                     };
  156.                     break;
  157.                 default:
  158.                     break;
  159.             }
  160.             break;
  161.             
  162.         case editMID:
  163.             if (!SystemEdit(theItem-1) && FrontObj->edit) 
  164.                 (*FrontObj->edit)((EditCmd)(theItem-1));
  165.             break;
  166.             
  167.         case scanMID:
  168.         
  169.             main_DoScan(theMenu, theItem);
  170.             break;
  171.  
  172.         default:
  173.             break;
  174.  
  175.     }; /* switch */
  176.     
  177.     /* Turn off the menu hiliting and return. */
  178.  
  179.     HiliteMenu(0);
  180. }
  181.     
  182. /*______________________________________________________________________
  183.  
  184.     Adjust - Adjust Menus.
  185. _____________________________________________________________________*/
  186.  
  187.  
  188. static void Adjust (void)
  189.  
  190. {
  191.     static WindKind        oldFrontKind = mainWind;    
  192.                                                             /* previous front window type */
  193.     static Boolean            oldScanning = false;    /* previous scanning context */
  194.     static Boolean            oldHelpMode = false;    /* previous help mode */
  195.     static Boolean            enableFlags[numMenus] = {true, true, true, true};
  196.                                                             /* menu enabled flags */
  197.                                                             
  198.     MenuHandle                fileM;                    /* handle to file menu */
  199.     MenuHandle                editM;                    /* handle to edit menu */
  200.     MenuHandle                scanM;                    /* handle to scan menu */
  201.     char                        *pMenuList;                /* pointer into menu list */
  202.     char                        *pMenuListEnd;            /* pointer to end of menu list */
  203.     Boolean                    reDrawMenuBar;            /* true if menu bar must be redrawn */
  204.     short                        menuIndex;                /* index into menu list */
  205.     MenuHandle                hMenu;                    /* handle to menu */
  206.     Boolean                    enabled;                    /* true if menu enabled */
  207.     
  208.     fileM = GetMHandle(fileMID);
  209.     editM = GetMHandle(editMID);
  210.     scanM = GetMHandle(scanMID);
  211.     
  212.     FrontKind = misc_GetWindKind(FrontWindow());
  213.     
  214.     if (HelpMode) {
  215.         if (oldHelpMode) return;
  216.         EnableItem(fileM, closeCommand);
  217.         EnableItem(fileM, saveAsCommand);
  218.         EnableItem(fileM, pageSetupCommand);
  219.         EnableItem(fileM, printCommand);
  220.         EnableItem(fileM, printOneCommand);
  221.         EnableItem(editM, undoCommand);
  222.         EnableItem(editM, cutCommand);
  223.         EnableItem(editM, copyCommand);
  224.         EnableItem(editM, pasteCommand);
  225.         EnableItem(editM, clearCommand);
  226.         EnableItem(editM, 0);
  227.         EnableItem(scanM, 0);
  228.     } else {
  229.         if (oldFrontKind == FrontKind  && oldScanning == Scanning &&
  230.             oldHelpMode == HelpMode) return;
  231.         if (FrontKind == daWind) {
  232.             EnableItem(fileM, closeCommand);
  233.             DisableItem(fileM, saveAsCommand);
  234.             DisableItem(fileM, pageSetupCommand);
  235.             DisableItem(fileM, printCommand);
  236.             DisableItem(fileM, printOneCommand);
  237.             if (Scanning) {
  238.                 DisableItem(scanM, 0);
  239.             } else {
  240.                 EnableItem(scanM, 0);
  241.             };
  242.             EnableItem(fileM, 0);
  243.             EnableItem(editM, undoCommand);
  244.             EnableItem(editM, cutCommand);
  245.             EnableItem(editM, copyCommand);
  246.             EnableItem(editM, pasteCommand);
  247.             EnableItem(editM, clearCommand);
  248.             EnableItem(editM, 0);
  249.         } else{
  250.             if (FrontObj->adjust) (*FrontObj->adjust)();
  251.         };
  252.     };
  253.     
  254.     /* Update the menu enabled flags, and redraw the menu bar
  255.         if necessary. */
  256.         
  257.     pMenuList = (char *)*MenuList;
  258.     pMenuListEnd = pMenuList + 6*numMenus;
  259.     pMenuList += 6;
  260.     reDrawMenuBar = false;
  261.     menuIndex = 0;
  262.     while (pMenuList <= pMenuListEnd) {
  263.         hMenu = *(MenuHandle*)(pMenuList);
  264.         enabled = (**hMenu).enableFlags & 1;
  265.         if (enabled != enableFlags[menuIndex]) {
  266.             reDrawMenuBar = true;
  267.             enableFlags[menuIndex] = enabled;
  268.         };
  269.         pMenuList += 6;
  270.         menuIndex++;
  271.     };
  272.     if (reDrawMenuBar) DrawMenuBar();
  273.     
  274.     oldFrontKind = FrontKind;
  275.     oldScanning = Scanning;
  276.     oldHelpMode = HelpMode;
  277. }
  278.  
  279. /*_____________________________________________________________________
  280.  
  281.     prog_Event - Fetch and Handle the Next Event.
  282.                 
  283.     This routine should be called to do all non-modal event processing.
  284.     It handles suspend, resume, and update events properly.  It also
  285.     keeps the initial integrity checksum going.
  286. _____________________________________________________________________*/
  287.  
  288.  
  289. void prog_Event (void)
  290.  
  291. {
  292.     EventRecord        event;            /* event */
  293.     short                mask;                /* event mask */
  294.     WindowPtr        whichWindow;    /* ptr to window clicked in */
  295.     WindowObject    *whichObj;        /* ptr to object for window clicked in */
  296.     short                partCode;        /* window part code */
  297.     short                key;                /* ascii code of key pressed */
  298.     unsigned long    newSize;            /* new window size */
  299.     long                sleep;            /* sleep time */
  300.     Boolean            eventAvail;        /* WaitNextEvent function result */
  301.     Point                where;            /* location of mouse down */
  302.     GrafPtr            savedPort;        /* saved grafport */
  303.     short                item;                /* dialog item */
  304.     Boolean            passEvent;        /* true if dialog event should be handled
  305.                                                 same as normal event */
  306.     Boolean            keyEvent;        /* true if keyDown or autoKey event */
  307.     Boolean            discardEvent;    /* true if dialog event should be discarded */
  308.     
  309.     /* Save the current grafport. */
  310.     
  311.     GetPort(&savedPort);
  312.     
  313.     /* Get the front window and a pointer to its object. */
  314.     
  315.     Front = FrontWindow();
  316.     FrontObj = (WindowObject*)((WindowPeek)Front)->refCon;
  317.  
  318.     /* Adjust menus. */
  319.  
  320.     Adjust();
  321.  
  322.     /* Take care of any periodic tasks for all open windows. */
  323.     
  324.     whichWindow = FrontWindow();
  325.     while (whichWindow) {
  326.         if (!utl_IsDAWindow(whichWindow)) {
  327.             whichObj = (WindowObject*)((WindowPeek)whichWindow)->refCon;
  328.             if (whichObj->periodic) {
  329.                 SetPort(whichWindow);
  330.                 (*whichObj->periodic)();
  331.             };
  332.         };
  333.         whichWindow = (WindowPtr)((WindowPeek)whichWindow)->nextWindow;
  334.     };
  335.     SetPort(savedPort);
  336.         
  337.     /* Initialize the event mask and the sleep time. */
  338.     
  339.     mask = everyEvent;
  340.     if ((Scanning && !FloppyWait) || !InForeground) mask ^= diskMask;
  341.     if (!Initialized) mask = updateMask | activMask;
  342.     sleep = (Scanning || InForeground) ? 0 : LongSleep;
  343.         
  344.     /* Get the next event, if any. */
  345.     
  346.     eventAvail = utl_WaitNextEvent(mask, &event, sleep, nil);
  347.     
  348.     /* Process extended keyboard keys. */
  349.     
  350.     if (keyEvent = event.what == keyDown || event.what == autoKey) {
  351.         key = event.message & charCodeMask;
  352.         switch (key) {
  353.             case homeKey:
  354.                 key = upArrow;
  355.                 event.modifiers |= cmdKey | shiftKey;
  356.                 break;
  357.             case endKey:
  358.                 key = downArrow;
  359.                 event.modifiers |= cmdKey | shiftKey;
  360.                 break;
  361.             case helpKey:
  362.                 key = '?';
  363.                 event.modifiers |= cmdKey;
  364.                 break;
  365.             case pageUpKey:
  366.                 key = upArrow;
  367.                 event.modifiers |= cmdKey;
  368.                 break;
  369.             case pageDownKey:
  370.                 key = downArrow;
  371.                 event.modifiers |= cmdKey;
  372.                 break;
  373.         };
  374.         event.message = (event.message & ~charCodeMask) | key;
  375.     };
  376.     
  377.     /* Check for and process dialog event.
  378.     
  379.         The event is passed through to the main body of code following if it
  380.         is a suspend or resume event (osEvt), a disk insertion event (diskEvt),
  381.         a command key event, or a mousedown event in help mode.
  382.         
  383.         Otherwise, all key events are preprocessed, and are discarded if the
  384.         preprocessor decides they are not legal.
  385.         
  386.         Remaining legal events are processed by DialogSelect.
  387.         
  388.         If DialogSelect returns true (an enabled item was involved), then the
  389.         item is postprocessed. */
  390.     
  391.     if (IsDialogEvent(&event)) {
  392.         passEvent = event.what == osEvt ||
  393.             event.what == diskEvt ||
  394.             keyEvent && (event.modifiers & cmdKey) ||
  395.             event.what == mouseDown && HelpMode;
  396.         if (!passEvent) {
  397.             discardEvent = false;
  398.             if (keyEvent && FrontObj->dialogPre)
  399.                 discardEvent = !(*FrontObj->dialogPre)((short)(event.message & charCodeMask));
  400.             if (!discardEvent && DialogSelect(&event, &whichWindow, &item)) {
  401.                 whichObj = (WindowObject*)((WindowPeek)whichWindow)->refCon;
  402.                 if (whichObj->dialogPost) {
  403.                     SetPort(whichWindow);
  404.                     (*whichObj->dialogPost)(item);
  405.                 };
  406.             };
  407.             SetPort(savedPort);
  408.             return;
  409.         };
  410.     };
  411.     
  412.     /* Return if there's no event to handle. */
  413.     
  414.     if (!eventAvail) return;
  415.     
  416.     /* Process the event. */
  417.     
  418.     switch (event.what) {
  419.     
  420.         case mouseDown:
  421.             
  422.             partCode = FindWindow(event.where, &whichWindow);
  423.             if (whichWindow && !utl_IsDAWindow(whichWindow)) 
  424.                 whichObj = (WindowObject*)((WindowPeek)whichWindow)->refCon;
  425.         
  426.             switch (partCode) {
  427.                 
  428.                 case inSysWindow:
  429.                 
  430.                     SystemClick(&event, whichWindow);
  431.                     break;
  432.                     
  433.                 case inMenuBar:
  434.                 
  435.                     MenuPick = true;
  436.                     Command(MenuSelect(event.where));
  437.                     break;
  438.                     
  439.                 case inGoAway:
  440.                 
  441.                     if (TrackGoAway(whichWindow, event.where))
  442.                         if (whichObj->close) (*whichObj->close)();
  443.                     break;
  444.                     
  445.                 case inDrag:
  446.                 
  447.                     DragWindow(whichWindow, event.where, &DragRect);
  448.                     whichObj->moved = true;
  449.                     break;
  450.                     
  451.                 case inGrow:
  452.                 
  453.                     SetPort(whichWindow);
  454.                     newSize = GrowWindow(whichWindow, event.where, 
  455.                         &whichObj->sizeRect);
  456.                     if (newSize && whichObj->grow) 
  457.                         (*whichObj->grow)((short)(newSize >> 16), (short)(newSize & 0xffff));
  458.                     whichObj->moved = true;
  459.                     break;
  460.                     
  461.                 case inZoomIn:
  462.                 case inZoomOut:
  463.                 
  464.                     if (TrackBox(whichWindow, event.where, partCode)) {
  465.                         SetPort(whichWindow);
  466.                         if (partCode == inZoomOut) wstm_ComputeStd(whichWindow);
  467.                         EraseRect(&whichWindow->portRect);
  468.                         ZoomWindow(whichWindow, partCode, false);
  469.                         if (whichObj->zoom) (*whichObj->zoom)();
  470.                         whichObj->moved = true;
  471.                     };
  472.                     break;
  473.                     
  474.                 case inContent:
  475.                 
  476.                     if (whichWindow != FrontWindow()) {
  477.                         SelectWindow(whichWindow);
  478.                     } else {
  479.                         SetPort(whichWindow);
  480.                         where = event.where;
  481.                         GlobalToLocal(&where);
  482.                         if (HelpMode) {
  483.                             if (whichObj->help) (*whichObj->help)(where);
  484.                         } else {
  485.                             if (whichObj->click) 
  486.                                 (*whichObj->click)(where, event.modifiers);
  487.                         };
  488.                     };
  489.                     break;
  490.                     
  491.             };
  492.             
  493.             break;
  494.             
  495.         case keyDown:
  496.         case autoKey:
  497.                 
  498.             SetPort(Front);
  499.             key = event.message & charCodeMask;
  500.             if ((event.modifiers & cmdKey) && key != upArrow &&
  501.                 key != downArrow) {
  502.                 if (key == '?' || key == '/') {
  503.                     HelpMode = !HelpMode;
  504.                     InitCursor();
  505.                 } else if (key == '.' && Scanning) {
  506.                     Scanning = FloppyWait = false;
  507.                     Canceled = true;
  508.                 } else {
  509.                     MenuPick = false;
  510.                     Command(MenuKey(event.message & charCodeMask));
  511.                 };
  512.             } else if (key == escapeKey && (HelpMode || Scanning)) {
  513.                 if (HelpMode) {
  514.                     HelpMode = false;
  515.                     InitCursor();
  516.                 } else {
  517.                     Scanning = FloppyWait = false;
  518.                     Canceled = true;
  519.                 };
  520.             } else {
  521.                 if (FrontObj->key) (*FrontObj->key)(key, event.modifiers);
  522.             };
  523.             break;
  524.             
  525.         case updateEvt:
  526.         
  527.             whichWindow = (WindowPtr)event.message;
  528.             whichObj = (WindowObject*)((WindowPeek)whichWindow)->refCon;
  529.             SetPort(whichWindow);
  530.             BeginUpdate(whichWindow);
  531.             EraseRect(&whichWindow->portRect);
  532.             if (whichObj->update) (*whichObj->update)();
  533.             EndUpdate(whichWindow);
  534.             break;
  535.             
  536.         case activateEvt:
  537.         
  538.             whichWindow = (WindowPtr)event.message;
  539.             whichObj = (WindowObject*)((WindowPeek)whichWindow)->refCon;
  540.             SetPort(whichWindow);
  541.             if (event.modifiers & activeFlag) {
  542.                 if (whichObj->activate) (*whichObj->activate)();
  543.             } else {
  544.                 if (whichObj->deactivate) (*whichObj->deactivate)();
  545.             };
  546.             break;
  547.             
  548.         case diskEvt:
  549.         
  550.             main_Disk(event.message);
  551.             break;
  552.             
  553.         case osEvt:    /* Suspend or resume event */
  554.         
  555.             /* Activate or deactivate the frontmost window */
  556.         
  557.             if (((event.message >> 24) & 0xff) != suspendResumeMessage) break;
  558.             InForeground = event.message & 1;
  559.             if (FrontKind != daWind) {
  560.                 SetPort(Front);
  561.                 if (InForeground) {
  562.                     if (FrontObj->activate) (*FrontObj->activate)();
  563.                 } else {
  564.                     if (FrontObj->deactivate) (*FrontObj->deactivate)();
  565.                 };
  566.             };
  567.             
  568.             /* Send suspend or resume message to all open windows. */
  569.             
  570.             whichWindow = FrontWindow();
  571.             while (whichWindow) {
  572.                 if (!utl_IsDAWindow(whichWindow)) {
  573.                     whichObj = (WindowObject*)((WindowPeek)whichWindow)->refCon;
  574.                     if (InForeground) {
  575.                         if (whichObj->resume) (*whichObj->resume)();
  576.                     } else {
  577.                         if (whichObj->suspend) (*whichObj->suspend)();
  578.                     };
  579.                 };
  580.                 whichWindow = (WindowPtr)((WindowPeek)whichWindow)->nextWindow;
  581.             };
  582.             
  583.             /* Adjust the cursor.  If resume event, remove notification. */
  584.             
  585.             if (InForeground) {
  586.                 misc_SetCursor();
  587.                 if (Notified) {
  588.                     Notified = false;
  589.                     if (Prefs.notifOption != notifAlert) 
  590.                         NMRemove((QElemPtr)&NotifRec);
  591.                 };
  592.             } else {
  593.                 InitCursor();
  594.             };
  595.             break;
  596.             
  597.     };
  598.     
  599.     /* Restore the saved grafPort. */
  600.     
  601.     SetPort(savedPort);
  602.  
  603. };
  604.     
  605. /*______________________________________________________________________
  606.  
  607.     Main - The Main Program.
  608. _____________________________________________________________________*/
  609.  
  610.  
  611. void main(void)
  612.  
  613. {
  614.     /* Initialize. */
  615.  
  616.     init_InitMem();
  617.     init_Initialize();
  618.     
  619.     /* If scanning station, start scan. */
  620.     
  621.     if (Prefs.scanningStation) scan_DoScan(autoScan, checkOp);
  622.  
  623.     /*    Main event loop. */
  624.     
  625.     while (!Done) prog_Event();
  626.     
  627.     /*    Terminate. */
  628.     
  629.     misc_WritePref();
  630. }
  631.